home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 2 / AACD 2.iso / AACD / Programming / fpc / compiler / ag386att.pas < prev    next >
Pascal/Delphi Source File  |  1998-09-24  |  26KB  |  758 lines

  1. {
  2.     $Id: ag386att.pas,v 1.1.1.1 1998/03/25 11:18:12 root Exp $
  3.     Copyright (c) 1996-98 by the FPC development team
  4.  
  5.     This unit implements an asmoutput class for i386 AT&T syntax
  6.  
  7.     This program is free software; you can redistribute it and/or modify
  8.     it under the terms of the GNU General Public License as published by
  9.     the Free Software Foundation; either version 2 of the License, or
  10.     (at your option) any later version.
  11.  
  12.     This program is distributed in the hope that it will be useful,
  13.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.     GNU General Public License for more details.
  16.  
  17.     You should have received a copy of the GNU General Public License
  18.     along with this program; if not, write to the Free Software
  19.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20.  
  21.  ****************************************************************************
  22. }
  23. unit ag386att;
  24.  
  25.     interface
  26.  
  27.     uses aasm,assemble;
  28.  
  29.     type
  30.       pi386attasmlist=^ti386attasmlist;
  31.       ti386attasmlist = object(tasmlist)
  32.         procedure WriteTree(p:paasmoutput);virtual;
  33.         procedure WriteAsmList;virtual;
  34.       end;
  35.  
  36.   implementation
  37.  
  38.     uses
  39.       dos,globals,systems,cobjects,i386,
  40.       strings,files,verbose
  41. {$ifdef GDB}
  42.       ,gdb
  43. {$endif GDB}
  44.       ;
  45.  
  46.     const
  47.       line_length = 70;
  48.     var
  49.       infile : pextfile;
  50.       includecount,
  51.       lastline : longint;
  52.  
  53.  
  54.     function getreferencestring(const ref : treference) : string;
  55.     var
  56.       s : string;
  57.     begin
  58.       if ref.isintvalue then
  59.        s:='$'+tostr(ref.offset)
  60.       else
  61.        begin
  62.          with ref do
  63.           begin
  64.           { have we a segment prefix ? }
  65.           { These are probably not correctly handled under GAS }
  66.           { should be replaced by coding the segment override  }
  67.           { directly! - DJGPP FAQ                              }
  68.             if segment<>R_DEFAULT_SEG then
  69.              s:=att_reg2str[segment]+':'
  70.             else
  71.              s:='';
  72.             if assigned(symbol) then
  73.              s:=s+symbol^;
  74.             if offset<0 then
  75.              s:=s+tostr(offset)
  76.             else
  77.              if (offset>0) then
  78.               begin
  79.                 if assigned(symbol) then
  80.                  s:=s+'+'+tostr(offset)
  81.                 else
  82.                  s:=s+tostr(offset);
  83.               end;
  84.             if (index<>R_NO) and (base=R_NO) then
  85.              Begin
  86.                s:=s+'(,'+att_reg2str[index];
  87.                if scalefactor<>0 then
  88.                 s:=s+','+tostr(scalefactor)+')'
  89.                else
  90.                 s:=s+')';
  91.              end
  92.             else
  93.              if (index=R_NO) and (base<>R_NO) then
  94.               s:=s+'('+att_reg2str[base]+')'
  95.              else
  96.               if (index<>R_NO) and (base<>R_NO) then
  97.                Begin
  98.                  s:=s+'('+att_reg2str[base]+','+att_reg2str[index];
  99.                  if scalefactor<>0 then
  100.                   s:=s+','+tostr(scalefactor)+')'
  101.                  else
  102.                   s := s+')';
  103.                end;
  104.           end;
  105.        end;
  106.       getreferencestring:=s;
  107.     end;
  108.  
  109.     function getopstr(t : byte;o : pointer) : string;
  110.     var
  111.       hs : string;
  112.     begin
  113.       case t of
  114.         top_reg : getopstr:=att_reg2str[tregister(o)];
  115.         top_ref : getopstr:=getreferencestring(preference(o)^);
  116.       top_const : getopstr:='$'+tostr(longint(o));
  117.      top_symbol : begin
  118.                     hs[0]:=chr(strlen(pchar(pcsymbol(o)^.symbol)));
  119.                     move(pchar(pcsymbol(o)^.symbol)^,hs[2],byte(hs[0]));
  120.                     inc(byte(hs[0]));
  121.                     hs[1]:='$';
  122.                     if pcsymbol(o)^.offset>0 then
  123.                      hs:=hs+'+'+tostr(pcsymbol(o)^.offset)
  124.                     else
  125.                      if pcsymbol(o)^.offset<0 then
  126.                       hs:=hs+tostr(pcsymbol(o)^.offset);
  127.                     getopstr:=hs;
  128.                   end;
  129.       else
  130.        internalerror(10001);
  131.       end;
  132.     end;
  133.  
  134.  
  135.     function getopstr_jmp(t : byte;o : pointer) : string;
  136.     var
  137.       hs : string;
  138.     begin
  139.       case t of
  140.        top_reg : getopstr_jmp:=att_reg2str[tregister(o)];
  141.        top_ref : getopstr_jmp:='*'+getreferencestring(preference(o)^);
  142.      top_const : getopstr_jmp:=tostr(longint(o));
  143.     top_symbol : begin
  144.                     hs[0]:=chr(strlen(pchar(pcsymbol(o)^.symbol)));
  145.                     move(pchar(pcsymbol(o)^.symbol)^,hs[1],byte(hs[0]));
  146.                     if pcsymbol(o)^.offset>0 then
  147.                      hs:=hs+'+'+tostr(pcsymbol(o)^.offset)
  148.                     else
  149.                      if pcsymbol(o)^.offset<0 then
  150.                       hs:=hs+tostr(pcsymbol(o)^.offset);
  151.                     getopstr_jmp:=hs;
  152.                  end;
  153.       else
  154.        internalerror(10001);
  155.       end;
  156.     end;
  157.  
  158.     var
  159.       MMXWarn : boolean;
  160.     procedure MMXWarning;
  161.     begin
  162.       if not MMXWarn then
  163.        begin
  164.          Message(assem_w_mmxwarning_as_281);
  165.          MMXWarn:=true;
  166.        end;
  167.     end;
  168.  
  169.  
  170. {****************************************************************************
  171.                             TI386ATTASMOUTPUT
  172.  ****************************************************************************}
  173.  
  174. {$ifdef GDB}
  175.     var
  176.       n_line : byte;    { different types of source lines }
  177. {$endif}
  178.  
  179.     const
  180.       ait_const2str : array[ait_const_32bit..ait_const_8bit] of string[8]=
  181.        (#9'.long'#9,'',#9'.short'#9,#9'.byte'#9);
  182.  
  183. {$ifdef MAKELIB}
  184.  
  185.      const
  186.         nameindex : longint = 0;
  187.      var
  188.         path, filename : string;
  189.  
  190.      procedure getnextname(var filename : string);
  191.  
  192.        begin
  193.           inc(nameindex);
  194.           if nameindex>999999 then
  195.             begin
  196.                exterror:=strpnew(' too many assembler files ');
  197.                fatalerror(user_defined);
  198.             end;
  199.           filename:='as'+tostr(nameindex);
  200.        end;
  201. {$endif MAKELIB}
  202.  
  203.     procedure ti386attasmlist.WriteTree(p:paasmoutput);
  204.     type
  205.       twowords=record
  206.         word1,word2:word;
  207.       end;
  208.     var
  209.       ch       : char;
  210.       hp       : pai;
  211.       consttyp : tait;
  212.       s        : string;
  213.       found    : boolean;
  214.       i,pos,l  : longint;
  215. {$ifdef GDB}
  216.       funcname  : pchar;
  217.       linecount : longint;
  218. {$endif GDB}
  219.  
  220.     begin
  221. {$ifdef GDB}
  222.       funcname:=nil;
  223.       linecount:=1;
  224. {$endif GDB}
  225.       hp:=pai(p^.first);
  226.       while assigned(hp) do
  227.        begin
  228.        { write debugger informations }
  229. {$ifdef GDB}
  230.          if cs_debuginfo in aktswitches then
  231.           begin
  232.             if not (hp^.typ in  [ait_external,ait_stabn,ait_stabs,
  233. {$ifdef MAKELIB}
  234.                    ait_cut,
  235. {$endif MAKELIB}
  236.                    ait_stab_function_name]) then
  237.              begin
  238.                if assigned(hp^.infile) and (pextfile(hp^.infile)<>infile)  then
  239.                 begin
  240.                   infile:=hp^.infile;
  241.                   inc(includecount);
  242.                   if (hp^.infile^.path^<>'') then
  243.                    begin
  244.                      AsmWriteLn(#9'.stabs "'+BsToSlash(FixPath(hp^.infile^.path^))+'",'+tostr(n_includefile)+
  245.                                 ',0,0,'+target_info.labelprefix+'text'+ToStr(IncludeCount));
  246.                    end;
  247.                   AsmWriteLn(#9'.stabs "'+FixFileName(hp^.infile^.name^+hp^.infile^.ext^)+'",'+tostr(n_includefile)+
  248.                              ',0,0,'+target_info.labelprefix+'text'+ToStr(IncludeCount));
  249.                   AsmWriteLn(target_info.labelprefix+'text'+ToStr(IncludeCount)+':');
  250.                 end;
  251.               { file name must be there before line number ! }
  252.                if (hp^.line<>lastline) and (hp^.line<>0) then
  253.                 begin
  254.                   if (n_line = n_textline) and assigned(funcname) and
  255.                      (target_info.use_function_relative_addresses) then
  256.                    begin
  257.                      AsmWriteLn(target_info.labelprefix+'l'+tostr(linecount)+':');
  258.                      AsmWriteLn(#9'.stabn '+tostr(n_line)+',0,'+tostr(hp^.line)+','+
  259.                                 target_info.labelprefix+'l'+tostr(linecount)+' - '+StrPas(FuncName));
  260.                      inc(linecount);
  261.                    end
  262.                   else
  263.                    AsmWriteLn(#9'.stabd'#9+tostr(n_line)+',0,'+tostr(hp^.line));
  264.                   lastline:=hp^.line;
  265.                 end;
  266.              end;
  267.           end;
  268. {$endif GDB}
  269.  
  270.          case hp^.typ of
  271.            ait_comment,    { we ignore comments because some GNU AS can't handle this }
  272.            ait_external:
  273.             ; { external is ignored }
  274.            ait_align:
  275.              begin
  276.                 { Fix Align bytes for Go32 which uses empty bits }
  277.                 l:=pai_align(hp)^.aligntype;
  278.                 if (target_info.target in [target_GO32V1,target_GO32V2]) then
  279.                  begin
  280.                    i:=0;
  281.                    while l>1 do
  282.                     begin
  283.                       l:=l shr 1;
  284.                       inc(i);
  285.                     end;
  286.                    l:=i;
  287.                  end;
  288.                 { use correct align opcode }
  289.                 AsmWrite(#9'.align '+tostr(l));
  290.                 if pai_align(hp)^.op<>0 then
  291.                  AsmWrite(','+tostr(pai_align(hp)^.op));
  292.                 AsmLn;
  293.              end;
  294.            ait_section:
  295.              begin
  296.                 asmwrite(#9'.section '+pai_section(hp)^.name^);
  297.                 asmln;
  298.              end;
  299.      ait_datablock : begin
  300.                        if pai_datablock(hp)^.is_global then
  301.                         AsmWrite(#9'.comm'#9)
  302.                        else
  303.                         AsmWrite(#9'.lcomm'#9);
  304.                        AsmWriteLn(StrPas(pai_datablock(hp)^.name)+','+tostr(pai_datablock(hp)^.size));
  305.                      end;
  306.    ait_const_32bit,
  307.    ait_const_16bit,
  308.     ait_const_8bit : begin
  309.                        AsmWrite(ait_const2str[hp^.typ]+tostr(pai_const(hp)^.value));
  310.                        consttyp:=hp^.typ;
  311.                        l:=0;
  312.                        repeat
  313.                          found:=(not (Pai(hp^.next)=nil)) and (Pai(hp^.next)^.typ=consttyp);
  314.                          if found then
  315.                           begin
  316.                             hp:=Pai(hp^.next);
  317.                             s:=','+tostr(pai_const(hp)^.value);
  318.                             AsmWrite(s);
  319.                             inc(l,length(s));
  320.                           end;
  321.                        until (not found) or (l>line_length);
  322.                        AsmLn;
  323.                      end;
  324.            ait_const_symbol:
  325.              AsmWriteLn(#9'.long'#9+StrPas(pchar(pai_const(hp)^.value)));
  326.            ait_const_rva:
  327.              AsmWriteLn(#9'.rva'#9+StrPas(pchar(pai_const(hp)^.value)));
  328.     ait_real_64bit : AsmWriteLn(#9'.double'#9+double2str(pai_double(hp)^.value));
  329.     ait_real_32bit : AsmWriteLn(#9'.single'#9+double2str(pai_single(hp)^.value));
  330.  ait_real_extended : AsmWriteLn(#9'.tfloat'#9+double2str(pai_extended(hp)^.value));
  331.                      { comp type is difficult to write so use double }
  332.           ait_comp : AsmWriteLn(#9'.double'#9+comp2str(pai_extended(hp)^.value));
  333.         ait_direct : begin
  334.                        AsmWritePChar(pai_direct(hp)^.str);
  335.                        AsmLn;
  336. {$IfDef GDB}
  337.                        if strpos(pai_direct(hp)^.str,'.data')<>nil then
  338.                          n_line:=n_dataline
  339.                        else if strpos(pai_direct(hp)^.str,'.text')<>nil then
  340.                          n_line:=n_textline
  341.                        else if strpos(pai_direct(hp)^.str,'.bss')<>nil then
  342.                          n_line:=n_bssline;
  343. {$endif GDB}
  344.                      end;
  345.         ait_string : begin
  346.                        pos:=0;
  347.                        for i:=1 to pai_string(hp)^.len do
  348.                         begin
  349.                           if pos=0 then
  350.                            begin
  351.                              AsmWrite(#9'.ascii'#9'"');
  352.                              pos:=20;
  353.                            end;
  354.                           ch:=pai_string(hp)^.str[i-1];
  355.                           case ch of
  356.                              #0, {This can't be done by range, because a bug in FPC}
  357.                         #1..#31,
  358.                      #128..#255 : s:='\'+tostr(ord(ch) shr 6)+tostr((ord(ch) and 63) shr 3)+tostr(ord(ch) and 7);
  359.                             '"' : s:='\"';
  360.                             '\' : s:='\\';
  361.                           else
  362.                            s:=ch;
  363.                           end;
  364.                           AsmWrite(s);
  365.                           inc(pos,length(s));
  366.                           if (pos>line_length) or (i=pai_string(hp)^.len) then
  367.                            begin
  368.                              AsmWriteLn('"');
  369.                              pos:=0;
  370.                            end;
  371.                         end;
  372.                      end;
  373.          ait_label : begin
  374.                        if (pai_label(hp)^.l^.is_used) then
  375.                         AsmWriteLn(lab2str(pai_label(hp)^.l)+':');
  376.                      end;
  377.         ait_labeled_instruction : begin
  378.                        if (pai_labeled(hp)^._operator>A_POPFD) then
  379.                         MMXWarning;
  380.                        AsmWriteLn(#9+att_op2str[pai_labeled(hp)^._operator]+#9+lab2str(pai_labeled(hp)^.lab));
  381.                      end;
  382.         ait_symbol : begin
  383.                        if pai_symbol(hp)^.is_global then
  384.                         AsmWriteLn('.globl '+StrPas(pai_symbol(hp)^.name));
  385.                        if target_info.target=target_LINUX then
  386.                         begin
  387.                            AsmWrite(#9'.type'#9+StrPas(pai_symbol(hp)^.name));
  388.                            if pai(hp^.next)^.typ in [ait_const_symbol,ait_const_32bit,
  389.                               ait_const_16bit,ait_const_8bit,ait_datablock] then
  390.                             AsmWriteLn(',@object')
  391.                            else
  392.                             AsmWriteLn(',@function');
  393.                         end;
  394.                        AsmWriteLn(StrPas(pai_symbol(hp)^.name)+':');
  395.                      end;
  396.    ait_instruction : begin { writes an instruction, highly table driven }
  397.                        if (pai386(hp)^._operator>A_POPFD) then
  398.                         MMXWarning;
  399.                        if (pai386(hp)^._operator=A_PUSH) and
  400.                           (pai386(hp)^.size=S_W) and
  401.                           (pai386(hp)^.op1t=top_const) then
  402.                         begin
  403. {$ifdef EXTDEBUG}
  404.                           AsmWriteLn('# GNU AS bug work around for pushw'#9+tostr(longint(pai386(hp)^.op1)));
  405. {$endif}
  406.                           AsmWriteLn(#9'.byte 0x66,0x68');
  407.                           AsmWriteLn(#9'.word '+tostr(longint(pai386(hp)^.op1)));
  408.                         end
  409.                        else
  410.                         begin
  411.                           s:=#9+att_op2str[pai386(hp)^._operator]+att_opsize2str[pai386(hp)^.size];
  412.                           if pai386(hp)^.op1t<>top_none then
  413.                            begin
  414.                            { call and jmp need an extra handling                          }
  415.                            { this code is only callded if jmp isn't a labeled instruction }
  416.                              if pai386(hp)^._operator in [A_CALL,A_JMP] then
  417.                               s:=s+#9+getopstr_jmp(pai386(hp)^.op1t,pai386(hp)^.op1)
  418.                              else
  419.                               begin
  420.                                 s:=s+#9+getopstr(pai386(hp)^.op1t,pai386(hp)^.op1);
  421.                                 if pai386(hp)^.op3t<>top_none then
  422.                                  begin
  423.                                    if pai386(hp)^.op2t<>top_none then
  424.                                     s:=s+','+getopstr(pai386(hp)^.op2t,
  425.                                       pointer(longint(twowords(pai386(hp)^.op2).word1)));
  426.                                     s:=s+','+getopstr(pai386(hp)^.op3t,
  427.                                     pointer(longint(twowords(pai386(hp)^.op2).word2)));
  428.                                  end
  429.                                 else
  430.                                  if pai386(hp)^.op2t<>top_none then
  431.                                   s:=s+','+getopstr(pai386(hp)^.op2t,pai386(hp)^.op2);
  432.                               end;
  433.                            end;
  434.                           AsmWriteLn(s);
  435.                         end;
  436.                      end;
  437. {$ifdef GDB}
  438.          ait_stabs : begin
  439.                        AsmWrite(#9'.stabs ');
  440.                        AsmWritePChar(pai_stabs(hp)^.str);
  441.                        AsmLn;
  442.                      end;
  443.          ait_stabn : begin
  444.                        AsmWrite(#9'.stabn ');
  445.                        AsmWritePChar(pai_stabn(hp)^.str);
  446.                        AsmLn;
  447.                      end;
  448.          ait_stab_function_name:
  449.            funcname:=pai_stab_function_name(hp)^.str;
  450. {$endif GDB}
  451. {$ifdef MAKELIB}
  452.           { used to split unit into tiny assembler files }
  453.              ait_cut :
  454.                begin
  455.                   outfile^.close;
  456.                   writeln(asmres,asbin+' -D -o '+path+filename+
  457.                     target_info.objext+' '+path+filename+target_info.asmext);
  458.                   getnextname(filename);
  459.                   outfile^.changename(path+filename+target_info.asmext);
  460.                   outfile^.rewrite;
  461.                   if p=codesegment then
  462.                     AsmWriteLn('.text')
  463.                   else
  464.                     AsmWriteLn('.data');
  465.                   { avoid empty files }
  466.                   while assigned(hp^.next) and (pai(hp^.next)^.typ=ait_cut) do
  467.                     hp:=pai(hp^.next);
  468.                end;
  469. {$endif MAKELIB}
  470.               else internalerror(10000);
  471.            end;
  472.            { omit extra new lines }
  473.            hp:=pai(hp^.next);
  474.         end;
  475.       end;
  476.  
  477.  
  478.     procedure ti386attasmlist.WriteAsmList;
  479. {$ifdef GDB}
  480.     var
  481.       p:dirstr;
  482.       n:namestr;
  483.       e:extstr;
  484. {$endif}
  485. {$ifdef MAKELIB}
  486.      path : string;
  487. {$endif MAKELIB}
  488.     begin
  489. {$ifdef EXTDEBUG}
  490.       if assigned(current_module^.mainsource) then
  491.        Comment(v_info,'Start writing att-styled assembler output for '+current_module^.mainsource^);
  492. {$endif}
  493.  
  494.       infile:=nil;
  495.       MMXWarn:=false;
  496.       includecount:=0;
  497. {$ifdef GDB}
  498.       if assigned(current_module^.mainsource) then
  499.        fsplit(current_module^.mainsource^,p,n,e)
  500.       else
  501.        begin
  502.          p:=inputdir;
  503.          n:=inputfile;
  504.          e:=inputextension;
  505.        end;
  506.     { to get symify to work }
  507.       AsmWriteLn(#9'.file "'+FixFileName(n+e)+'"');
  508.     { stabs }
  509.       n_line:=n_bssline;
  510.       if (cs_debuginfo in aktswitches) then
  511.        begin
  512.          if (p<>'') then
  513.           AsmWriteLn(#9'.stabs "'+BsToSlash(p)+'",'+tostr(n_sourcefile)+',0,0,Ltext0');
  514.          AsmWriteLn(#9'.stabs "'+n+e+'",'+tostr(n_sourcefile)+',0,0,Ltext0');
  515.          AsmWriteLn('Ltext0:');
  516.        end;
  517.       infile:=current_module^.sourcefiles.files;
  518.     { main source file is last in list }
  519.       while assigned(infile^._next) do
  520.        infile:=infile^._next;
  521.       lastline:=0;
  522. {$endif GDB}
  523. {$ifdef MAKELIB}
  524.          path:=p+n+'.dir';
  525.          mkdir(path);
  526.          path:=path+'/';
  527.          nameindex:=0;
  528.          outfile^.close;
  529.          getnextname(filename);
  530.          outfile^.changename(path+filename+target_info.asmext);
  531.          outfile^.rewrite;
  532. {$endif MAKELIB}
  533.  
  534.       { there should be nothing but externals so we don't need to process
  535.       WriteTree(externals); }
  536.       WriteTree(debuglist);
  537.  
  538.     { code segment }
  539.       AsmWriteln('.text');
  540. {$ifdef GDB}
  541.       n_line:=n_textline;
  542. {$endif GDB}
  543.       WriteTree(codesegment);
  544.  
  545.       AsmWriteLn('.data');
  546. {$ifdef EXTDEBUG}
  547.       AsmWriteLn(#9'.ascii'#9'"compiled by FPC '+version_string+'\0"');
  548.       AsmWriteLn(#9'.ascii'#9'"target: '+target_info.target_name+'\0"');
  549. {$endif EXTDEBUG}
  550. {$ifdef GDB}
  551.       n_line:=n_dataline;
  552. {$endif GDB}
  553.       DataSegment^.insert(new(pai_align,init(4)));
  554.       WriteTree(datasegment);
  555.       WriteTree(consts);
  556.  
  557.     { makes problems with old GNU ASes
  558.       AsmWriteLn('.bss');
  559.       bssSegment^.insert(new(pai_align,init(4))); }
  560. {$ifdef GDB}
  561.       n_line:=n_bssline;
  562. {$endif GDB}
  563.       WriteTree(bsssegment);
  564.  
  565.       AsmLn;
  566.       if assigned(importssection) then
  567.         begin
  568.            writetree(importssection);
  569.         end;
  570.       if assigned(exportssection) then
  571.         begin
  572.            writetree(exportssection);
  573.         end;
  574.       if assigned(resourcesection) then
  575.         begin
  576.            writetree(resourcesection);
  577.         end;
  578. {$ifdef EXTDEBUG}
  579.       if assigned(current_module^.mainsource) then
  580.        comment(v_info,'Done writing att-styled assembler output for '+current_module^.mainsource^);
  581. {$endif EXTDEBUG}
  582.     end;
  583.  
  584.  
  585. end.
  586. {
  587.   $Log: ag386att.pas,v $
  588.   Revision 1.1.1.1  1998/03/25 11:18:12  root
  589.   * Restored version
  590.  
  591.   Revision 1.3  1998/03/24 21:48:29  florian
  592.     * just a couple of fixes applied:
  593.          - problem with fixed16 solved
  594.          - internalerror 10005 problem fixed
  595.          - patch for assembler reading
  596.          - small optimizer fix
  597.          - mem is now supported
  598.  
  599.   Revision 1.2  1998/03/10 16:27:36  pierre
  600.     * better line info in stabs debug
  601.     * symtabletype and lexlevel separated into two fields of tsymtable
  602.     + ifdef MAKELIB for direct library output, not complete
  603.     + ifdef CHAINPROCSYMS for overloaded seach across units, not fully
  604.       working
  605.     + ifdef TESTFUNCRET for setting func result in underfunction, not
  606.       working
  607.  
  608.   Revision 1.1  1998/03/10 01:26:09  peter
  609.     + new uniform names
  610.  
  611.   Revision 1.30  1998/03/09 12:58:10  peter
  612.     * FWait warning is only showed for Go32V2 and $E+
  613.     * opcode tables moved to i386.pas/m68k.pas to reduce circular uses (and
  614.       for m68k the same tables are removed)
  615.     + $E for i386
  616.  
  617.   Revision 1.29  1998/03/02 01:48:06  peter
  618.     * renamed target_DOS to target_GO32V1
  619.     + new verbose system, merged old errors and verbose units into one new
  620.       verbose.pas, so errors.pas is obsolete
  621.  
  622.   Revision 1.28  1998/03/01 22:46:00  florian
  623.    + some win95 linking stuff
  624.    * a couple of bugs fixed:
  625.      bug0055,bug0058,bug0059,bug0064,bug0072,bug0093,bug0095,bug0098
  626.  
  627.   Revision 1.27  1998/02/28 00:20:21  florian
  628.     * more changes to get import libs for Win32 working
  629.  
  630.   Revision 1.26  1998/02/27 22:27:51  florian
  631.     + win_targ unit
  632.     + support of sections
  633.     + new asmlists: sections, exports and resource
  634.  
  635.   Revision 1.25  1998/02/26 11:57:02  daniel
  636.   * New assembler optimizations commented out, because of bugs.
  637.   * Use of dir-/name- and extstr.
  638.  
  639.   Revision 1.24  1998/02/23 02:58:24  carl
  640.     * bugfix of compiling with extdebug defined
  641.  
  642.   Revision 1.23  1998/02/22 23:03:00  peter
  643.     * renamed msource->mainsource and name->unitname
  644.     * optimized filename handling, filename is not seperate anymore with
  645.       path+name+ext, this saves stackspace and a lot of fsplit()'s
  646.     * recompiling of some units in libraries fixed
  647.     * shared libraries are working again
  648.     + $LINKLIB <lib> to support automatic linking to libraries
  649.     + libraries are saved/read from the ppufile, also allows more libraries
  650.       per ppufile
  651.  
  652.   Revision 1.22  1998/02/15 21:15:59  peter
  653.     * all assembler outputs supported by assemblerobject
  654.     * cleanup with assembleroutputs, better .ascii generation
  655.     * help_constructor/destructor are now added to the externals
  656.     - generation of asmresponse is not outputformat depended
  657.  
  658.   Revision 1.21  1998/02/13 22:26:15  peter
  659.     * fixed a few SigSegv's
  660.     * INIT$$ was not written for linux!
  661.     * assembling and linking works again for linux and dos
  662.     + assembler object, only attasmi3 supported yet
  663.     * restore pp.pas with AddPath etc.
  664.  
  665.   Revision 1.20  1998/02/13 10:34:35  daniel
  666.    * Made Motorola version compilable.
  667.    * Fixed optimizer
  668.  
  669.   Revision 1.19  1998/02/12 11:49:42  daniel
  670.   Yes! Finally! After three retries, my patch!
  671.  
  672.   Changes:
  673.  
  674.   Complete rewrite of psub.pas.
  675.   Added support for DLL's.
  676.   Compiler requires less memory.
  677.   Platform units for each platform.
  678.  
  679.   Revision 1.18  1998/02/08 15:13:34  florian
  680.     * correct output of mmx register names
  681.  
  682.   Revision 1.17  1998/02/04 21:58:41  florian
  683.     + MMX registers for output added
  684.  
  685.   Revision 1.16  1998/01/27 23:33:24  peter
  686.     * a ' was placed wrong
  687.  
  688.   Revision 1.15  1998/01/26 18:52:56  peter
  689.     * Align with go32 is in empty bits, not in bytes like linux
  690.  
  691.   Revision 1.14  1998/01/19 09:32:30  michael
  692.   * Shared Lib and GDB/RHIDE Bufixes from Peter Vreman.
  693.  
  694.   Revision 1.13  1998/01/13 23:11:00  florian
  695.     + class methods
  696.  
  697.   Revision 1.12  1998/01/12 01:08:21  michael
  698.   * Small fix to make shared libs possible. (From Peter Vreman)
  699.  
  700.   Revision 1.11  1998/01/07 00:16:35  michael
  701.   Restored released version (plus fixes) as current
  702.  
  703.   Revision 1.10  1997/12/15 14:09:17  florian
  704.     * now no stabs are generated if debugging info is off
  705.  
  706.   Revision 1.9  1997/12/09 13:25:20  carl
  707.   + added pai_align abstract instruction
  708.   * probably some bugfixes (can't remember!)
  709.  
  710.   Revision 1.8  1997/12/05 14:43:57  carl
  711.   * bugfix of compiler crash with ait_labeled_instr
  712.  
  713.   Revision 1.7  1997/12/04 12:20:44  pierre
  714.     +* MMX instructions added to att output with a warning that
  715.        GNU as version >= 2.81 is needed
  716.        bug in reading of reals under att syntax corrected
  717.  
  718.   Revision 1.6  1997/12/01 17:42:50  pierre
  719.      + added some more functionnality to the assembler parser
  720.  
  721.   Revision 1.4  1997/11/28 18:14:19  pierre
  722.    working version with several bug fixes
  723.  
  724.   Revision 1.2  1997/11/27 17:36:44  carl
  725.   * make it compile under BP (line too long errors)
  726.  
  727.   Revision 1.1.1.1  1997/11/27 08:32:50  michael
  728.   FPC Compiler CVS start
  729.  
  730.  
  731.   Pre-CVS log:
  732.  
  733.   CEC   Carl-Eric Codere
  734.   FK    Florian Klaempfl
  735.   PM    Pierre Muller
  736.   +     feature added
  737.   -     removed
  738.   *     bug fixed or changed
  739.  
  740.   History:
  741.       30th september 1996:
  742.          + unit started (FK)
  743.       15th october 1996:
  744.          + ti386attasmoutput class started (FK)
  745.       28th november 1996:
  746.          ! debugging for simple programs (FK)
  747.       26th february 1997:
  748.          + op2str array completed with work of Daniel Manitone (FK)
  749.       25th september 1997:
  750.          * compiled by comment ifdef'ed (FK)
  751.       13th november 1997:
  752.          * added single and extended const (PM)
  753.          + added support for scaling = 0 (CEC)
  754.            (is this ok??? Tested under 2.8.1.)
  755.       14th november 1997:
  756.          + added POPFD
  757. }
  758.